home *** CD-ROM | disk | FTP | other *** search
- #define STRICT_WINDOWS 1
- #include <Memory.h>
- #include <Palettes.h>
- #include <Dialogs.h>
- #include <Gestalt.h>
- #include "Dim_text_3.h"
-
- static pascal void Dim_text_proc( short byteCnt, Ptr textAddr,
- Point numerPt, Point denomPt );
- static void Gray_frame_rect( Rect *bounds );
- static pascal void Gray_frame_draw_proc( short depth, short dev_flags,
- GDHandle dev, Rect *bounds );
-
- /* ---------------------------------------------------------------------
- Dim_text This is a group of routines for dimming text
- items in dialogs. As is, it assumes that you are
- not using the dialog's refCon for anything else.
-
- This code can be used freely. I ask that you tell me about any
- improvements that you think of.
-
- James W. Walker December 4, 1995
- JWWalker@kagi.com
- 76367.2271@compuserve.com
- ---------------------------------------------------------------------
- */
-
- typedef struct Dim_list_el {
- struct Dim_list_el *next;
- Rect bounds;
- short item_num;
- Boolean editable;
- } Dim_list_el;
-
- typedef struct {
- Dim_list_el *dim_list;
- ModalFilterUPP User_filter;
- } Dim_data;
-
-
- /* ---------------------------------------------------------------------
- Get_dim_data Macro to get the list head.
- Set_dim_data Macro to store the list head.
-
- Just used to encapsulate the use of the refCon,
- so that if you need to store the list head
- somewhere else you will only need to change this.
- ---------------------------------------------------------------------
- */
- #ifdef __cplusplus
- inline Dim_data * Get_dim_data( DialogRef dp )
- {
- return (Dim_data *) GetWRefCon( GetDialogWindow( dp ) );
- }
-
- inline void Set_dim_data( DialogRef dp, Dim_data *dim_head )
- {
- SetWRefCon( GetDialogWindow( dp ), (long) dim_head );
- }
- #else
- #define Get_dim_data( dp ) ((Dim_data *) GetWRefCon( GetDialogWindow( dp ) ))
- #define Set_dim_data( dp, dim_head ) SetWRefCon( GetDialogWindow( dp ), (long) dim_head )
- #endif
-
- /* ---------------------------------------------------------------------
- SetDialogKeyboardFocusItem This is the one part of my code that
- is not quite compatible with using the
- STRICT_WINDOWS flag for Copland-readiness.
- In non-STRICT_WINDOWS terms what it does is
- ((DialogPeek) dialog)->editField = item-1;
- ---------------------------------------------------------------------
- */
- #ifdef __cplusplus
- inline void SetDialogKeyboardFocusItem( DialogRef dialog, short item )
- {
- *(SInt16 *) (((UInt8 *) dialog) + 164) = item - 1;
- }
- #else
- #define SetDialogKeyboardFocusItem(dialog, item) do{*(SInt16 *) (((UInt8 *) dialog) + 164) = item - 1;} while (false);
- #endif
-
- /* ---------------------------------------------------------------------
- Init_dimmer Set up a dialog for dimming text. Call it once, soon
- after creating the dialog.
-
- Inputs:
- DialogRef dp The dialog in which we will dim text.
-
- ModalFilterUPP User_filter
- What you would have used as a modal filter
- routine if you were not using Dim_filter_proc.
- You can pass NULL, and then Dim_filter_proc
- will call the standard filter.
- ---------------------------------------------------------------------
- */
- void Init_dimmer( DialogRef dp, ModalFilterUPP User_filter )
- {
- Dim_data *dim_head;
-
- dim_head = (Dim_data *) NewPtrClear( sizeof(Dim_data) );
- if (dim_head)
- {
- if (User_filter == NULL)
- GetStdFilterProc( &dim_head->User_filter );
- else
- dim_head->User_filter = User_filter;
- // Store the pointer where we can find it later
- Set_dim_data( dp, dim_head );
- }
- }
-
- /* ---------------------------------------------------------------------
- Dim_filter_proc Dialog filter that you pass to ModalDialog.
- ---------------------------------------------------------------------
- */
- pascal Boolean Dim_filter_proc( DialogRef theDialog, EventRecord *theEvent, short *itemHit )
- {
- Boolean result = false;
- Dim_data *dim_head;
- Dim_list_el *this_el;
- RgnHandle boundsRgn;
-
- dim_head = Get_dim_data( theDialog );
- if (dim_head != NULL)
- {
- if ( (theEvent->what == updateEvt)
- && (theDialog == (DialogRef) theEvent->message) )
- {
- boundsRgn = NewRgn();
- for (this_el = dim_head->dim_list; this_el != NULL; this_el = this_el->next )
- {
- if (this_el->editable)
- {
- Gray_frame_rect( &this_el->bounds );
- }
- RectRgn( boundsRgn, &this_el->bounds );
- TextMode( grayishTextOr );
- UpdateDialog( theDialog, boundsRgn );
- TextMode( srcOr );
- ValidRect( &this_el->bounds );
- }
- DisposeRgn( boundsRgn );
- }
-
- result = CallModalFilterProc( dim_head->User_filter, theDialog, theEvent, itemHit );
- }
-
- return result;
- }
-
- /* ---------------------------------------------------------------------
- Dispose_dimmer Called once after you are through with a dialog.
- ---------------------------------------------------------------------
- */
- void Dispose_dimmer( DialogRef dp )
- {
- Dim_data *dim_head;
- Dim_list_el *this_el, *next;
-
- dim_head = Get_dim_data(dp);
- if (dim_head)
- {
- this_el = dim_head->dim_list;
- while (this_el != NULL)
- {
- EraseRect( &this_el->bounds );
- InvalRect( &this_el->bounds );
- next = this_el->next;
- DisposePtr( (Ptr) this_el );
- this_el = next;
- }
-
- DisposePtr( (Ptr) dim_head );
- }
- }
-
- /* ---------------------------------------------------------------------
- Dim_text Set the dimming state of a text item.
- ---------------------------------------------------------------------
- */
- void Dim_text( DialogRef dp, short item, Boolean dim )
- {
- Dim_data *dim_head;
- Dim_list_el *dimmable, *predecessor;
- Rect iRect;
- Handle iHandle;
- short iType;
- short disable_flag;
-
- dim_head = Get_dim_data(dp);
- if (dim_head != NULL)
- {
- GetDialogItem( dp, item, &iType, &iHandle, &iRect );
- disable_flag = iType & itemDisable;
-
- // Try to find the right item number in the list.
- dimmable = dim_head->dim_list;
- while ( (dimmable != NULL) && (dimmable->item_num != item) )
- {
- dimmable = dimmable->next;
- }
-
- if ( (dimmable == NULL) && dim ) // if it should be and isn't, dim it
- {
- dimmable = (Dim_list_el *)
- NewPtrClear( sizeof(Dim_list_el) );
- if (dimmable)
- {
- dimmable->next = dim_head->dim_list;
- dim_head->dim_list = dimmable;
- dimmable->item_num = item;
- dimmable->editable = (iType & editText) != 0;
- dimmable->bounds = iRect;
- if (dimmable->editable)
- {
- InsetRect( &dimmable->bounds, -3, -3 );
- /*
- To dim an editable text item, we need to turn it
- into a static text item, and also take some care
- that it is not showing the insertion point or a
- selection range.
- */
- if (item == GetDialogKeyboardFocusItem( dp ) )
- {
- SelectDialogItemText( dp, item, 0, 0 );
- }
- SetDialogItem( dp, item, statText | disable_flag,
- iHandle, &iRect );
- if (item == GetDialogKeyboardFocusItem( dp ) )
- SetDialogKeyboardFocusItem( dp, 0 );
- InvalRect( &dimmable->bounds );
- }
- else
- {
- InvalRect( &iRect );
- }
- }
- }
- else if ( (dimmable != NULL) && !dim ) // undim it
- {
- // Remove it from the list
- if (dim_head->dim_list == dimmable)
- {
- dim_head->dim_list = dimmable->next;
- }
- else
- {
- predecessor = dim_head->dim_list;
- while (predecessor->next != dimmable)
- {
- predecessor = predecessor->next;
- }
- predecessor->next = dimmable->next;
- }
-
- if (dimmable->editable)
- {
- SetDialogItem( dp, item, editText | disable_flag,
- iHandle, &iRect );
- SelectDialogItemText( dp, item, 0, 0 );
- EraseRect( &iRect );
- }
- InvalRect( &dimmable->bounds );
-
- // Delete the list element
- DisposePtr( (Ptr) dimmable );
- }
- }
- }
-
-
-
- /* ---------------------------------------------------------------------
- Gray_frame_draw_proc DeviceLoop drawing procedure called
- by Gray_frame_rect.
- ---------------------------------------------------------------------
- */
- static pascal void Gray_frame_draw_proc( short depth, short /* dev_flags */,
- GDHandle dev, Rect *bounds )
- {
- RGBColor fore_color, back_color, gray_color;
- long gray_pat[2];
-
- if (depth > 1)
- {
- GetForeColor( &fore_color );
- GetBackColor( &back_color );
- gray_color = fore_color;
- GetGray( dev, &back_color, &gray_color );
- RGBForeColor( &gray_color );
- }
- else
- {
- gray_pat[0] = gray_pat[1] = 0xAA55AA55L;
- PenPat( (ConstPatternParam) gray_pat );
- }
-
- FrameRect( bounds );
-
- if (depth > 1)
- {
- RGBForeColor( &fore_color );
- }
- else
- {
- PenNormal();
- }
- }
-
- /* ---------------------------------------------------------------------
- Gray_frame_rect Draw a gray rectangle; true gray
- if possible, dithered otherwise.
- ---------------------------------------------------------------------
- */
- static void Gray_frame_rect( Rect *bounds )
- {
- RgnHandle save_clip, draw_rgn;
- DeviceLoopDrawingUPP Draw_UPP;
-
- PenNormal();
- save_clip = NewRgn();
- GetClip( save_clip );
- draw_rgn = NewRgn();
- RectRgn( draw_rgn, bounds );
- SetClip( draw_rgn );
- Draw_UPP = NewDeviceLoopDrawingProc( Gray_frame_draw_proc );
- DeviceLoop( draw_rgn, Draw_UPP, (long) bounds, 0 );
- DisposeRoutineDescriptor( Draw_UPP );
- SetClip( save_clip );
- DisposeRgn( draw_rgn );
- DisposeRgn( save_clip );
- PenNormal();
- }
-